#!/usr/bin/perl
#
#	Author:  Brandon Shields (brandon.d.shields at gmail dot com)
#	Based on source by: Steve Adeff from ragetvgrab
#		and the guys at The Shepherd (http://svn.whuffy.com)
#
#	Project lives at: http://code.google.com/p/mythvideo-scanner/

BEGIN
{
	#Add some search locations to the path
	$command = $0;
#	$CWD = $ENV{PWD};
	$command =~ s/\/[^\/]*$//;
	push(@INC,"$command");
	push(@INC,"/usr/local/share/mythvideo-scanner/");
	push(@INC,"/usr/share/mythvideo-scanner/");
}

#this library has been modified to return all hits form a DB query
use modules::MythTV;

use Getopt::Long;

my $version=1.7;
my $help=0;
my $opt_posters=0;
my $opt_nonexist=0;
my $opt_blacklist=0;
my $opt_dryrun=0;

my $npost=0;

#Process options
GetOptions (
	'help' => \$help,
	'posters' => \$opt_posters,
	'nonexist' => \$opt_nonexist,
	'blacklist' => \$opt_blacklist,
	'dryrun' => \$opt_dryrun,
);

if($help == 1 || ($opt_posters == 0 && $opt_nonexist == 0 && $opt_blacklist == 0))
{
	print "mythvideo-cleaner\n";
	print "version: $version\n";
	print "\n";
	print "Usage: mythvideo-cleaner <options>\n";
	print "\n";
	print "Options:\n";
	print "--posters     Clean up the covers directory.\n";
	print "--nonexist    Remove non-existent videos from database.\n";
	print "--blacklist   Remove blacklisted items from database.\n";
	print "--dryrun      Testrun, don't actually modify the database.\n";
	print "\n";
	exit 0;
}

#get host name
my $hostname = `/bin/hostname`;
chomp($hostname);
print "Using settings for ". $hostname ."\n";;

#get DB schema version
my $db_schema;
my $tmp = MythTV::query("SELECT data FROM settings WHERE value LIKE 'mythvideo.DBSchemaVer'");
$db_schema = $tmp->[0]->[0];
if( ! $db_schema){
	my $tmp = MythTV::query("SELECT data FROM settings WHERE value LIKE 'DBSchemaVer'");
	$db_schema = $tmp->[0]->[0];
}
print "Mythvideo Database schema is ".$db_schema.", suggests Mythtv version " ;
if( $db_schema < 1028 ) {
	print "<= 0.21\n";
}
elsif( $db_schema < 1032) {
	print "==0.22\n";
}
elsif( $db_schema < 1037) {
	print "==0.23\n";
}
elsif( $db_schema == 1037 ) {
	print "==0.24\n";
}
elsif( $db_schema < 1317 ) {
	print "== 0.25...0.26\n";
}
elsif( $db_schema == 1317 ) {
	print "== 0.27\n";
}
elsif( $db_schema > 1317 ) {
	print ">= 0.28\n";
}

#This is the current blacklist.
my @blacklist = ('sample','subs','VIDEO_TS','proof');

my $remove;
my $nexist=0;
my $blacklist=0;
my $npost=0;

my @video_group;
#   Storage group
if( $db_schema >= 1028 )
{
	$dir = MythTV::query("SELECT dirname FROM storagegroup WHERE groupname = 'Videos' AND hostname = '$hostname'");
	if(@$dir>0)
	{
		foreach my $item (@$dir)
		{
			my $tmp;
			#remove tailing slash
			$tmp = $item->[0];
			$tmp =~ s/\/?$//;
			push(@video_group,$tmp);
		}
	}
}

my $vids = MythTV::query("SELECT filename FROM videometadata");
if(@$vids>0)
{
	foreach my $video (@$vids)
	{
		my $filename = getFullpath($video->[0]);
		$remove =0;
		#if file not exist or is a directory
		if( $opt_nonexist==1 )
		{
			if( length $filename == 0 )
			{
				$remove = 1;
				$nexist++;
			}
		}
		if($opt_blacklist==1)
		{
			foreach my $ignore (@blacklist)
			{
				if ("$filename" =~ /\/$ignore\//i)
				{
					$blacklist++;
					$remove = 1;
					next;
				}
			}
		}
		if($remove)
		{
			my $short;
			my $delimited;
			$myshort = $filename;
			$myshort =~ s/(\/[^\/]*\/)(.*?)(\/[^\/]*.{0,40})$/\1\.\.\.\3/;
			$delimited = $video->[0];
			$delimited =~ s/\'/\\\'/g;
			print "Removing from db: ".$myshort."\n";
			if($opt_dryrun == 0)
			{
				$dbh = MythTV::open_connection();
				$dbh->do("DELETE FROM videometadata WHERE filename = '$delimited'");
				MythTV::close_connection();
			}
			else
			{
				print "Query: DELETE FROM videometadata WHERE filename = '".$delimited."'\n";
			}
		}
	}
}

if($opt_posters)
{
	cleanArtDir('coverfile','Coverart','VideoArtworkDir');
	if($db_schema >= 1028 )
	{
		cleanArtDir('banner','Banners','mythvideo.bannerDir');
		cleanArtDir('fanart','Fanart','mythvideo.fanartDir');
		cleanArtDir('screenshot','Screenshots','mythvideo.screenshotDir');
	}
}
print "deleted: ".$nexist." blacklisted: ".$blacklist."\n";
print "Artwork deleted: ".$npost."\n";

sub cleanArtDir
{
	my $ArtCol=shift;
	my $ArtGroup=shift;
	my $ArtSetting=shift;

	my $artPath='';
	my $artGroup;
	my @files;

	@artGroup = getStorageGroup($ArtGroup);
	if(@artGroup){
		$artPath = $artGroup[0];
	}
	else{
		$artPath = getSetting($ArtSetting);
	}
	#remove tailing slash
	$artPath =~ s/\/?$//;
	push(@artGroup,$artPath);

	print "Cleaning Artwork directory: '" .$artPath."'\n";

	opendir(hDir, $artPath) || die "failed to open ".$artPath;
	@files=readdir(hDir);
	closedir(hDir);
	#check db for existance
	foreach $artFile (@files)
	{
		#ignore . and .. special folders
		next if $artFile =~ /^\.?\.$/;
		next if $artFile !~ /.*\.jpg$/i;
		#MySQL queries don't like single quotes, so lets delimit them
		my $qFilename = getGroupSubpath($artPath."/".$artFile,\@artGroup);
		$qFilename =~ s/\'/\\\'/g;
		my $title = MythTV::query("SELECT title FROM videometadata WHERE $ArtCol LIKE '$qFilename'");
		if(@$title==0)
		{
			print "Remove: ".$artFile."\n";
			$npost++;
			if($opt_dryrun == 0)
			{
				if(!unlink $artPath."/".$artFile)
				{
					print "  FAILED\n";
				}
			}
		}
		else
		{
		#	print $artFile." in use by ".$title->[0]->[0]."\n";
		}
	}
}


sub getSetting
{
	my $data='';
	my $result;
	my $value = shift;
	$result = MythTV::query("SELECT data FROM settings WHERE value = '$value' AND ( hostname = '$hostname' or hostname is null )");
	if(@$result>0)
	{
		$data = $result->[0]->[0];
	}
	else
	{
		print "Setting not found: $value\n";
	}
	return $data;
}

sub getStorageGroup
{
	my $groupname = shift;
	my @group;
	#   Storage group
	if( $db_schema >= 1028 )
	{
		$dir = MythTV::query("SELECT dirname FROM storagegroup WHERE groupname = '$groupname' AND hostname = '$hostname'");
		if(@$dir>0)
		{
			foreach my $item (@$dir)
			{
				my $tmp;
				#remove tailing slash
				$tmp = $item->[0];
				$tmp =~ s/\/?$//;
				push(@group,$tmp);
			}
		}
		else
		{
			print "Storagegroup \'$groupname\' not defined\n";
		}
	}
	return @group;
}

sub getGroupSubpath
{
	my $filename = shift;
	my $ref = shift;
	my @group = @$ref;
	#  Set the default return path to complete filename
	my $subpath = $filename;
	foreach my $group_dir (@group)
	{
		if(length $group_dir > 0 )
		{
			if( $filename =~ /^$group_dir\/(.*)/ )
			{
				$subpath = $1;
#				print "Found item in video group: $group_dir\n";
#				print "                           $subpath\n";
				last
			}
		}
	}
	return $subpath;
}

sub getFullpath
{
	my $filename = shift;
	#  Set return string to blank, so if it does not exist, it will
	#   have length of zero
	my $fullfilename = "";
	#  Check if file has absolute path
	if( $filename =~ /^\// )
	{
		if( -f $filename )
		{
			$fullfilename = $filename;
		}
	}
	else
	{
		foreach my $group_dir (@video_group)
		{
			if(length $group_dir > 0 )
			{
				if( -f $group_dir."/".$filename )
				{
					$fullfilename = $group_dir."/".$filename;
					last
				}
			}
		}
	}
	return $fullfilename;
}
